/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package okhttp3.internal.connection;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.http.RealInterceptorChain;

/**负责与服务器建立连接
 * ConnectInterceptor在Request阶段建立连接，处理方式也很简单，创建了两个对象：
HttpCodec：用来编码HTTP requests和解码HTTP responses
RealConnection：连接对象，负责发起与服务器的连接。
这里事实上包含了连接、连接池等一整套的Okhttp的连接机制
 * Opens a connection to the target server and proceeds to the next interceptor.
 * @author chenli
 *
 */
public final class ConnectInterceptor implements Interceptor {
	public final OkHttpClient client;

	public ConnectInterceptor(OkHttpClient client) {
		this.client = client;
	}

	@Override
	public Response intercept(Chain chain) throws IOException {
		RealInterceptorChain realChain = (RealInterceptorChain) chain;
		Request request = realChain.request();
		StreamAllocation streamAllocation = realChain.streamAllocation();

		// We need the network to satisfy this request. Possibly for validating a
		// conditional GET.
		// 我们需要网络来满足这个要求。 可能用于验证条件GET
		boolean doExtensiveHealthChecks = !request.method().equals("GET");
		// HttpCodec 用来编码请求并解码响应
		HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks);
		// RealConnection 用来向服务器发起连接
		// 此处 可用的 含义主要为，可以直接写入HTTP请求的数据：
		// 设置了HTTP代理的HTTP请求，与代理建立好TCP连接；
		// 设置了HTTP代理的HTTPS请求，与HTTP服务器建立通过HTTP代理的隧道连接，并完成TLS握手；
		// 设置了HTTP代理的HTTP/2请求，与HTTP服务器建立通过HTTP代理的隧道连接，并完成与服务器的TLS握手及协议协商；
		// 设置了SOCKS代理的HTTP请求，通过代理与HTTP服务器建立好连接；
		// 设置了SOCKS代理的HTTPS请求，通过代理与HTTP服务器建立好连接，并完成TLS握手；
		// 设置了SOCKS代理的HTTP/2请求，通过代理与HTTP服务器建立好连接，并完成与服务器的TLS握手及协议协商；
		// 无代理的HTTP请求，与服务器建立好TCP连接；
		// 无代理的HTTPS请求，与服务器建立TCP连接，并完成TLS握手；
		// 无代理的HTTP/2请求，与服务器建立好TCP连接，完成TLS握手及协议协商。
		RealConnection connection = streamAllocation.connection();

		return realChain.proceed(request, streamAllocation, httpCodec, connection);
	}

}
